#include "CurveSkeletonModel.h"
#include <fstream>
#include "StarlabException.h"
#include <QtOpenGL>

using namespace std;
CurveSkeletonModel::CurveSkeletonModel(QString path, QString name) : Model(path,name){}

void CurveSkeletonModel::readFromFile(QString path){
    std::string inputLine;
    ifstream file( qPrintable(path) );
    float x,y,z;
    int n1, n2;
    int degree;
    int numberOfNodes;
    int numberOfEdges;
    int nCount = 0;
    int nEdges = 0;

    nodes.clear();
    edges.clear();

    /// Check file
    if(!file.is_open()) 
        throw StarlabException("Cannot open skeleton file");

    /// Read header
    if(!file.eof() && getline(file, inputLine)){
        if(sscanf(inputLine.c_str(), "# D:%d NV:%d NE:%d", &degree, &numberOfNodes, &numberOfEdges) != 3){
            printf("Error reading skeleton file (check header).");
            printf("\n%d - %d - %d\n", degree, numberOfNodes, numberOfEdges);
            return;
        }
    }
    
    /// Parse file
    while (!file.eof()){
        getline(file, inputLine);
        switch(inputLine[0]){
        case 'v':
                if(sscanf(inputLine.c_str(), "v %f %f %f", &x,&y,&z) == 3)
                        nodes.push_back( SkeletonNode(x,y,z, nCount++) );
                break;

        case 'e':
                if(sscanf(inputLine.c_str(), "e %d %d", &n1, &n2) == 2)
                        edges.push_back( SkeletonEdge(&nodes[n1 - 1], &nodes[n2 - 1], nEdges++) );
                break;
        }
    
    }    
    file.close();
}



void CurveSkeletonModel::render(){
    glClear(GL_DEPTH_BUFFER_BIT);
    glDisable(GL_LIGHTING);
        render_nodes();
        render_edges();
    glEnable(GL_LIGHTING);
} 
void CurveSkeletonModel::render_nodes(){
    glPointSize(4.0f);
    glEnable(GL_POINT_SMOOTH);    
    for(int i = 0; i < (int) nodes.size(); i++){
        glColor3f(0.9f, 0.2f, 0.2f);
        glPointSize(7.0f);
        glBegin(GL_POINTS);
            glVertex3f(nodes[i].x, nodes[i].y, nodes[i].z);
        glEnd();

        // White Border
        glPointSize(10.0f);
        glColor3f(1,1,1);

        glBegin(GL_POINTS);
            glVertex3f(nodes[i].x, nodes[i].y, nodes[i].z);
        glEnd();
    }
}
void CurveSkeletonModel::render_edges(){
    glPointSize(4.0f);
    glColor3f(1,0,0);
    glEnable(GL_POINT_SMOOTH);
    
    float oldLineWidth = 0;
    glGetFloatv(GL_LINE_WIDTH, &oldLineWidth);
    glLineWidth(1.5f);

    glEnable(GL_BLEND); 
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glBegin(GL_LINES);
            for(int i = 0; i < (int)edges.size(); i++){
                glColor3f(0.5f, 0.0f, 0.2f);
                glVertex3f(edges[i].n1->x, edges[i].n1->y, edges[i].n1->z);
                glColor3f(1.0f, 0.2f, 0.2f);
                glVertex3f(edges[i].n2->x, edges[i].n2->y, edges[i].n2->z);
            }
        glEnd();
    glDisable(GL_BLEND);
}

